package skyhyun;

public class J26_TypeCasting {
	// 모든 클래스의 조상
		// 모든 클래스는 자동적으로 java.lang.Object 를 확장함
		// 즉, Object 클래스는 자바에서 궁극의 super 클래스임
		// 기본적으로 Object 클래스에는 7개의 메서드가 정의되어 있고, 하위 클래스에서는 이것을
		// 재정의해서 적절히 사용가능
		// equals - 기존 객체와 매개변수로 전달된 객체와 비교
		//              객체 비교가 제대로 이뤄질려면 메서드를 재정의하고 구현해야 함
		// hashcode - 객체의 해시코드를 출력함
		//                   객체는 일반적으로 heap 에 생성됨
		//                   heap에 생성된 객체의 메모리 주소를 바탕으로 만들어지는 유일한 코드값을 의미
		// toString - 객체에 대한 설명을 출력함

	// is - a 관계확인
	// 특정 객체가 어떤 유형과 동일한지 또는 상속 관계인지 알아볼 때 instanceof 예약어를 사용

		public static void main(String[] args) {
			Object obj = new Object();
			
			J25_Animal a = new J25_Animal();
			J25_Fish f = new J25_Fish();
			a = new J25_Fish();
			// Fish는 Animal을 확장했기 때문에 Animal 객체에 Fish 객체를 받을 수 있음
			// 하위 객체를 상위 객체로 cast 하는 경우 이것을 upcasting 이라 함
			
			// f = (J25_Fish)new J25_Animal();
			// 상위 객체를 하위 객체로 cast 하는 경우 이것을 downcasting 이라 함
			// 이때 명시적으로 괄호안에 cast 할 클래스 자료형을 명시
			
			// 스타크래프트 게임내에서 해병, 불곰, 의무병을 생산하는 경우
			Marine m1 = new Marine();
			Firebat f1 = new Firebat();
			Medic d1 = new Medic();
			
			// 다형성을 근거로 테란유닛 생산 (upcasting)
			// 즉, Marine 유닛은 상황에 따라 TerranUnits 도 될 수 있다는 의미
			TerranUnits t1 = new Marine();
			t1.sayUnit();
			t1.sayUnit( (Marine)t1 );
			TerranUnits t2 = new Firebat();	// upcasting
			t2.sayUnit();
			t2.sayUnit( (Firebat)t2 );		// downcasting
			TerranUnits t3 = new Medic();
			t3.sayUnit();
			
			AllianceUnit a1 = new Human();
			AllianceUnit a2 = new Wolf();
			AllianceUnit a3 = new Nom();
			
			// 객체유형 확인하기
			J26_TypeCasting t = new J26_TypeCasting();
			if (t instanceof java.lang.Object)
				System.out.println("t 는 Object의 자손");
			if (m1 instanceof TerranUnits)	// is -a
				System.out.println("해병은 테란유닛의 자손");
			if (m1 instanceof Marine)			// 동질성
				System.out.println("m1은 해병임");
		}
	}

	// TerranUnit - Marine, Firebat, Medic
	class TerranUnits { 
		public void sayUnit() {
			System.out.println( "저는 테란유닛입니다" );
		}
		public void sayUnit( Marine m ) {
			System.out.println( "저는 해병입니다" );
		}
		public void sayUnit( Firebat m ) {
			System.out.println( "저는 불곰입니다" );
		}
		public void sayUnit( Medic m ) {
			System.out.println( "저는 의무병입니다" );
		}
	}
	class Marine extends TerranUnits { }
	class Firebat extends TerranUnits { }
	class Medic extends TerranUnits { }

	// AllianceUnit - Human, Wolf, Nom
	class AllianceUnit { }
	class Human extends AllianceUnit { }
	class Wolf extends AllianceUnit { }
	class Nom extends AllianceUnit { }
